package com.gitee.fsmxm.thinking.in.concurrent.basic;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 目前操作：使用线程并行优化串行操作
 * <p>获取未对账订单
 * <p>获取派送订单
 * <p>执行对账操作
 * <p>差异写入差异库
 */
public class _09_CountDownLatch_OrdersSample {

    public static class Order {
        int orderId;
        public Order(int id) {
            orderId = id;
        }
    }

    public static class OrderService {
        // 获取未对账订单
        public List<Order> getPOrders() {
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return Arrays.asList(new Order(1), new Order(2));
        }
        // 获取派送订单
        public List<Order> getDOrders() {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return Arrays.asList(new Order(1), new Order(2));
        }
        // 执行对账操作
        public Object check(List<Order> pos, List<Order> dos) {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return new Object();
        }
        // 差异写入差异库
        public void save(Object diff) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static final OrderService service = new OrderService();
    // 串行
    private static void testInOrder() {
        while (true) {
            long t1 = System.currentTimeMillis();
            List<Order> pOrders = service.getPOrders();
            List<Order> dOrders = service.getDOrders();
            Object diff = service.check(pOrders, dOrders);
            service.save(diff);
            System.out.println("串行操作，耗时： " + (System.currentTimeMillis() - t1) + "毫秒");
        }
    }
    // 获取未对账订单和获取派送订单并行
    private static void testInThread() throws InterruptedException {
        while (true) {
            long t1 = System.currentTimeMillis();
            AtomicReference<List<Order>> pOrders = new AtomicReference<>();
            Thread th1 = new Thread(() -> {
                pOrders.set(service.getPOrders());
            }, "t1");
            AtomicReference<List<Order>> dOrders = new AtomicReference<>();
            Thread th2 = new Thread(() -> {
                dOrders.set(service.getDOrders());
            }, "t2");
            th1.start();
            th2.start();
            th1.join();
            th2.join();
            Object diff = service.check(pOrders.get(), dOrders.get());
            service.save(diff);
            System.out.println("并行操作，耗时： " + (System.currentTimeMillis() - t1) + "毫秒");
        }
    }

    // 获取未对账订单和获取派送订单并行，并使用线程池和CountDownLatch
    private static void testInThreadPool() throws InterruptedException {
        final ExecutorService executor =   Executors.newFixedThreadPool(2);
        while (true) {
            CountDownLatch latch = new CountDownLatch(2);
            long t1 = System.currentTimeMillis();
            AtomicReference<List<Order>> pOrders = new AtomicReference<>();
            executor.execute(() -> {
                pOrders.set(service.getPOrders());
                latch.countDown();
            });
            AtomicReference<List<Order>> dOrders = new AtomicReference<>();
            executor.execute(() -> {
                dOrders.set(service.getDOrders());
                latch.countDown();
            });
            latch.await();
            Object diff = service.check(pOrders.get(), dOrders.get());
            service.save(diff);
            System.out.println("并行操作，耗时： " + (System.currentTimeMillis() - t1) + "毫秒");
        }
    }

    public static void main(String[] args) throws InterruptedException {
//        testInOrder();
//        testInThread();
        testInThreadPool();
    }

}
